#include "crossbit/ShadowPage.h"

using namespace crossbit;

ShadowPage::ShadowPage()
{
		page_table = new PageData*[PAGE_NUM];
		//page_table = (PageData**)UTIL::XTMalloc( sizeof(PageData*) * V_ADDRESS_SPACE / PAGE_SIZE );

		for( int i = 0; i < PAGE_NUM; i++ )
				page_table[i] = NULL;
}

void ShadowPage::readMem( XTMemAddr addr, XTInt32 size )
{
		//PageDate *page = page_table[ PAGE_INDEX(addr) ];

		//return *(XTUint32*)addr;
	if( (addr&0x3fff0000 !=0x3FFF0000) && addr > SYSCALL::sys_brk )
	{
		printf("Access error! Over Sys_Brk! addr: %x, sys_brk: %x\n", addr, SYSCALL::sys_brk);
	}
}

#include <iostream>
void ShadowPage::writeMem( XTMemAddr addr, XTInt32 size, XTUint32 value )
{
		PageData *&page = page_table[ PAGE_INDEX(addr) ];
		if( NULL == page )
		{
				page = new PageData;
				UTIL::XTMemcpy( (void*)page->mem_data, (void*)PAGE_ALIGN(addr), PAGE_SIZE);
		}

		switch( size )
		{
				case WORD:
						*(XTUint32*)(page->mem_data+PAGE_OFFSET(addr)) = value;
						*(XTUint32*)addr = value;
						break;
				case HALFWORD:
						*(XTUint16*)(page->mem_data+PAGE_OFFSET(addr)) = value;
						*(XTUint16*)addr = value;
						break;
				case BYTE:
						*(XTUint8*)(page->mem_data+PAGE_OFFSET(addr)) = value;
						*(XTUint8*)addr = value;
						break;
		}
}

void ShadowPage::dumpMemData( XTFile fd )
{
		PageData *page;
		for( int i = 0; i < PAGE_NUM; i++ )
		{
			page = page_table[i];
			if ( page != NULL )
			{
				SYSCALL::XTWrite(fd, &i, sizeof(XTUint32));	
				SYSCALL::XTWrite(fd, page->mem_data, PAGE_SIZE);	
			}
		}	
}


void ShadowPage::loadMemData( XTFile fd )
{
		PageData *page;
		int index;


		int ret = SYSCALL::XTRead(fd, &index, sizeof(XTUint32));	
		while( ret && ret != -1 )
		{
			PageData *&page = page_table[index];	
			if( NULL == page )
				page = new PageData;
			SYSCALL::XTRead(fd, page->mem_data, PAGE_SIZE);	
			XTMemAddr addr = index<<12;
			UTIL::XTMemcpy( (void*)PAGE_ALIGN(addr), (void*)page->mem_data, PAGE_SIZE);
				//std::cout<<std::hex<<"0x"<<addr<<std::endl;
				
			ret = SYSCALL::XTRead(fd, &index, sizeof(XTUint32));	
		}
}
